package github.kawaiior.yuanchuxiuzhen.network.packet;


import github.kawaiior.yuanchuxiuzhen.common.capability.entity.ManaPower;
import github.kawaiior.yuanchuxiuzhen.core.init.GongFaInit;
import github.kawaiior.yuanchuxiuzhen.core.registry.ModCapability;
import github.kawaiior.yuanchuxiuzhen.network.NetworkRegistryHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.network.PacketDistributor;

import java.util.function.Supplier;

public class UpdateManaPacket{

    private ManaPower power = null;

    public UpdateManaPacket(PlayerEntity player){
        LazyOptional<ManaPower> capability = player.getCapability(ModCapability.MANA_POWER);
        capability.ifPresent((power)->{
            this.power = power;
        });
    }

    public UpdateManaPacket(ManaPower power){
        this.power = power;
    }

    public UpdateManaPacket(){

    }

    public ManaPower getPower(){
        return this.power;
    }

    public static void encode(UpdateManaPacket packet, PacketBuffer buffer) {
        ManaPower power = packet.getPower();

        if (power==null){
            buffer.writeBoolean(false);
            return;
        }

        buffer.writeBoolean(true);

        buffer.writeInt(power.getLevel());
        buffer.writeInt(power.getInnerLevel());
        buffer.writeInt(power.getExperience());

        buffer.writeFloat(power.getMaxHealth());
        buffer.writeFloat(power.getMana());
        buffer.writeFloat(power.getMaxMana());
        buffer.writeFloat(power.getAttack());
        buffer.writeFloat(power.getDefense());
        buffer.writeFloat(power.getManaRecovery());

        buffer.writeFloat(power.getMerit());
        buffer.writeInt(power.getThunderTribulation());
        buffer.writeFloat(power.getEvilSpirit());

        buffer.writeInt(power.getRefining());
        buffer.writeInt(power.getAlchemy());
        buffer.writeInt(power.getCharacter());
        buffer.writeInt(power.getFragment());

        buffer.writeBoolean(power.isVitality());
        buffer.writeByteArray(power.getManaRootArray());
        buffer.writeByteArray(power.getGongFaArray());
        buffer.writeInt(power.getLearningGongFa());
        buffer.writeInt(power.getGongFaExp());
    }

    public static UpdateManaPacket decode(PacketBuffer buffer){
        boolean hasPower = buffer.readBoolean();
        ManaPower power = null;
        if (hasPower) {
            power = new ManaPower(buffer.readInt(), buffer.readInt(), buffer.readInt(),
                    buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(),
                    buffer.readFloat(),
                    buffer.readFloat(), buffer.readInt(), buffer.readFloat(),
                    buffer.readInt(), buffer.readInt(), buffer.readInt(), buffer.readInt(),
                    buffer.readBoolean(), buffer.readByteArray(5),
                    buffer.readByteArray(GongFaInit.GONG_FAS.size()), buffer.readInt(), buffer.readInt());
        }

        return new UpdateManaPacket(power);
    }

    public static void handlePacket(UpdateManaPacket packet, Supplier<NetworkEvent.Context> content){
        NetworkEvent.Context context = content.get();
        context.enqueueWork(()->{
            if (context.getDirection().getReceptionSide().isClient()) {
                onClientCustomPack(packet, context);
            }
            if (context.getDirection().getReceptionSide().isServer()){
                onServerCustomPack(packet, context);
            }
        });
        context.setPacketHandled(true);
    }

    @OnlyIn(Dist.CLIENT)
    public static void onClientCustomPack(UpdateManaPacket packet, NetworkEvent.Context context){
        Minecraft mc = Minecraft.getInstance();
        ClientPlayerEntity player = mc.player;
        assert player != null;
        LazyOptional<ManaPower> capability = player.getCapability(ModCapability.MANA_POWER);
        capability.ifPresent((power)->{
            power.setPower(packet.getPower());
        });
        ManaPower.update(player);
    }

    public static void onServerCustomPack(UpdateManaPacket packet, NetworkEvent.Context context){
        ServerPlayerEntity player = context.getSender();
        assert player != null;
        NetworkRegistryHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new UpdateManaPacket(player));
        ManaPower.update(player);
    }

}
